﻿using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;

namespace QuartzJob
{
    public class SchedulerServer
    {
        /// <summary>
        /// 调用定时任务
        /// </summary>
        public static void SynChronizeStart()
        {
            StartQuartz();
        }
        /// <summary>
        /// 开始定时任务
        /// </summary>
        private static void StartQuartz()
        {
            // 创建调度器工厂
            ISchedulerFactory schedulerFactory = new StdSchedulerFactory();


            IScheduler scheduler = schedulerFactory.GetScheduler();
            scheduler.Clear();

            // 获取所有实现 IJobModel 接口的类型
            var typeList = GetClassByInterface(typeof(IJobModel));

            foreach (var type in typeList)
            {
                var obj = Activator.CreateInstance(type) as IJobModel;
                if (obj == null)
                {
                    continue;
                }

                string jobName = obj.JobName;
                string jobTime = obj.JobTime;

                if (string.IsNullOrEmpty(jobTime))
                {
                    throw new Exception($"还未设置任务 {jobName} 的时间调度");
                }

                // 2. 创建一个具体的作业
                IJobDetail job = JobBuilder.Create(type)
                    .WithIdentity(jobName, "JobGroup")
                    .Build();

                // 3. 创建并配置一个触发器
                ITrigger trigger = TriggerBuilder.Create()
                    .WithIdentity(jobName, "JobGroup")
                    .StartNow()
                    .WithCronSchedule(jobTime) // 时间表达式
                    .Build();

                // 4. 加入作业调度池中
                scheduler.ScheduleJob(job, trigger);
            }

            // 启动调度器
            scheduler.Start();

        }

        /// <summary>
        /// 获取所有继承 IJobModel接口的类
        /// </summary>
        /// <param name="interfaceType"></param>
        /// <returns></returns>
        public static IEnumerable<Type> GetClassByInterface(Type interfaceType)
        {
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (var type in assembly.GetTypes())
                {
                    foreach (var t in type.GetInterfaces())
                    {
                        if (t == interfaceType)
                        {
                            yield return type;
                            break;
                        }
                    }
                }
            }
        }
    }
}
